<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>2代理模式</title>
  </head>

  <body>
    <script>
      // 虽然代理模式非常有用，但我们在编写程序的时候，往往不需要先去预测是否需要使用代理模式。
      // 当真正发现不方便直接访问某个对象的时候，再编写代理也不迟

      // 本体对象暴露接口名 代理对象进行处理
      // 在 JavaScript 开发中最常用的是虚拟代理和缓存代理

      // ========== 1.虚拟代理-图片预加载==========
      var myImage = (function () {
        var imgNode = document.createElement('img');
        document.body.appendChild(imgNode);
        return {
          setSrc: function (src) {
            imgNode.src = src;
          },
        };
      })();

      var proxyImage = (function () {
        var img = new Image();
        img.onload = function () {
          myImage.setSrc(this.src);
        };
        return {
          setSrc: function (src) {
            myImage.setSrc('file:// /C:/Users/svenzeng/Desktop/loading.gif');
            img.src = src;
          },
        };
      })();
      proxyImage.setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg');

      class MyImage {
        constructor() {
          this.img = document.createElement('img');
          document.body.appendChild(this.img);
        }
        setSrc(loadingSrc) {
          this.img.src = loadingSrc;
        }
      }

      class ProxyImage {
        _myImage = null;
        constructor(_myImage) {
          this._myImage = _myImage;
          this.img = new Image();
          const _this = this;
          this.img.onload = function () {
            _this._myImage.setSrc(_this.img.src);
          };
        }

        setSrc(src) {
          this._myImage.setSrc('file:// /C:/Users/svenzeng/Desktop/loading.gif');
          this.img.src = src;
        }
      }
      new proxyImage(new MyImage()).setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg');

      // ==========2.缓存代理-处理函数==========
      var mult = function () {
        console.log('开始计算乘积');
        var a = 1;
        for (var i = 0, l = arguments.length; i < l; i++) {
          a = a * arguments[i];
        }
        return a;
      };
      // 现在加入缓存代理函数：
      var proxyMult = (function () {
        var cache = {};
        return function () {
          var args = Array.prototype.join.call(arguments, ',');
          if (args in cache) {
            return cache[args];
          }
          return (cache[args] = mult.apply(this, arguments));
        };
      })();
      proxyMult(1, 2, 3, 4); // 输出：24
      proxyMult(1, 2, 3, 4); // 输出：24
      // 当我们第二次调用 proxyMult( 1, 2, 3, 4 )的时候，本体 mult 函数并没有被计算，proxyMult
      // 直接返回了之前缓存好的计算结果。
    </script>
  </body>
</html>
